package com.saohuobang.test.listener;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.saohuobang.test.service.FrameworkService;
import com.saohuobang.test.service.MonitorThread;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 作者 yaohua.liu
 * 日期 2015-12-18 15:28
 * 包名 com.saohuobang.test.listener
 * 说明 ...
 */
public class PropertyFileListener {

    private final Logger logger = LoggerFactory.getLogger(PropertyFileListener.class);
    private FrameworkService frameworkService;

    private static PropertyFileListener instance = new PropertyFileListener();

    public static PropertyFileListener getInstance() {
        return instance;
    }

    private PropertyFileListener() {
    }


    public void startMonitor(List<String> filePaths) {
        if (filePaths == null || filePaths.size() == 0) {
            return;
        }
        WatchService watchService = null;
        try {
            watchService = FileSystems.getDefault().newWatchService();
        } catch (IOException e) {
            logger.error("开启文件监听服务失败:msg = {}", e.getMessage(), e);
            return;
        }
        List<Path> needMonitorPath = Lists.newArrayList();

        for (String path : filePaths) {
            Path business = getNeedMonitorPath(path);
            if (business != null) {
                needMonitorPath.add(business);
            }
        }

        for (Path path : needMonitorPath) {
            logger.info("注册监听的路径：{}", path);
            try {
                path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE);
            } catch (IOException e) {
                logger.error("注册监听的路径失败:msg = {}", e.getMessage(), e);
            }
        }
        new MonitorThread(this, watchService, frameworkService).start();
        /*while (openListener) {
            List<WatchEvent<?>> events = null;
            WatchKey wk = null;
            try {
                wk = watchService.take();
                events = wk.pollEvents();
            } catch (InterruptedException e) {
                logger.error("注册监听的路径失败:msg = {}", e.getMessage(), e);
                break;
            }
            for (WatchEvent<?> event : events) {
                // final Path changed = (Path) event.context();
                String fileName = event.context().toString();
                String kind = event.kind().name();
                logger.info("监听到文件有修改,file_name = {},操作类型 = {}", fileName, kind);
                if ((Objects.equal(kind, "ENTRY_CREATE") && checkBusinessRootDir(fileName)) || (Objects.equal(kind, "ENTRY_MODIFY") && this.checkFileType(fileName))) {
                    stopMonitor();
                    logger.info("重启test 服务。。。。。。");
                    if (frameworkService != null) {
                        frameworkService.restart();
                    }
                    //break;
                }
            }
            // reset the key
            boolean valid = wk.reset();
            if (!valid) {
                logger.info("Key has been unregisterede");
            }
        }*/
    }

    /**
     * 根据目录路径获取需要监听的 Path
     *
     * @param dirPath
     * @return
     */
    private Path getNeedMonitorPath(String dirPath) {
        if (Strings.isNullOrEmpty(dirPath)) {
            return null;
        }
        File file = new File(dirPath);
        if (!file.exists() || !file.isDirectory()) {
            return null;
        }
        return Paths.get(dirPath);
    }

    /**
     * 停止文件监控
     *
     * @return
     */
    public boolean stopMonitor() {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            return false;
        }
        return true;
    }

    public void setFrameworkService(FrameworkService frameworkService) {
        this.frameworkService = frameworkService;
    }
}
